<?

/**
* Cria tabelas no banco de dados baseado na estrutura definida no arquivo em formato .ini
*/
class Qi_Db_Ini2Db
{
	private $schema = array();

	private $nomes_padroes = array(
		"id" => "INT unsigned NOT NULL auto_increment, PRIMARY KEY (%s)",
		"ativo" => "tinyint(1) unsigned NOT NULL default '0'",
		"preco" => "DECIMAL(10, 2) NOT NULL"
	);

	private $nomes_padroes_regexp = array(
		'_id$' => "INT unsigned",
		'_em$' => "DATETIME",
		'_at$' => "DATETIME",
		'_ate$' => "DATETIME",
		'^qtde_|_qtde$' => "INT NOT NULL"
	);

	private $tipos_padroes = array(
		"int" => "INT unsigned NOT NULL",
		"varchar" => "VARCHAR(255) NOT NULL",
		"char" => "CHAR(1) NOT NULL",
		"text" => "TEXT",
		"date" => "DATE",
		"time" => "TIME",
		"datetime" => "DATETIME",
		"moeda" => "DECIMAL(10, 2) NOT NULL",
		"bool" => "tinyint(1) unsigned NOT NULL default '0'"
	);

	/**
	* Cria apartir de um arquivo ini ou um array no mesmo formato gerado por parse_ini_file
	*/
	public function __construct($arquivo_ini_ou_array)
	{
		$this->schema = is_array($arquivo_ini_ou_array) 
						? $arquivo_ini_ou_array 
						: parse_ini_file($arquivo_ini_ou_array, true);
	}

	public function exec($drop = false)
	{
		foreach($this->schema as $tabela => $campos):
			$tabela = strtolower($tabela);
			if ($drop) $this->drop_table($tabela);
			$sql = $this->gerar_create_table($tabela, $campos);
			$this->query($sql);
		endforeach;
	}

	private function drop_table($tabela)
	{
		$this->query("DROP TABLE IF EXISTS $tabela");
	}

	private function query($sql)
	{
		Qi_Db::query($sql);
	}

	private function gerar_create_table($tabela, $campos)
	{
		$campos_gerados = array();
		foreach($campos as $nome => $conf):
			$nome = strtolower($nome);
			$campos_gerados[$nome] = $this->gerar_campos($nome, $conf);
		endforeach;
		$definicao = implode(",\n", $campos_gerados);
		$if_not_exists = $this->if_not_exists($tabela);
		$sql = "\nCREATE TABLE $if_not_exists $tabela\n(\n$definicao\n)\n";
		return $sql;
	}

	private function gerar_campos($nome, $conf)
	{
		$definicao = $this->achar_definicao_para($nome, $conf);
		return "\t$nome $definicao";
	}

	private function achar_definicao_para($nome, $conf)
	{
		if ( isset($this->nomes_padroes[$nome]) )
			return sprintf($this->nomes_padroes[$nome], $nome);

		elseif ($regexp = $this->test_nomes_padroes_regexp($nome))
			return $regexp;

		elseif ( isset($this->tipos_padroes[$conf]) )
			return sprintf($this->tipos_padroes[$conf], $nome);

		return "VARCHAR(255) NOT NULL";
	}

	private function test_nomes_padroes_regexp($nome)
	{
		foreach($this->nomes_padroes_regexp as $regexp => $conf):
			if ( preg_match("/$regexp/", $nome) )
				return $conf;
		endforeach;
		return false;
	}

	private function if_not_exists($tabela)
	{
		return "IF NOT EXISTS";
	}
}

?>